unit Checkers.InputManager;

interface

uses
  Classes,
  Windows,
  Messages,
  Dialogs,
  Controls,
  Forms,
  SysUtils,
//GLScene
  GLSGenerics,
  GLCrossPlatform,
//Project
  Checkers.Visualizer;

type
  TCheckersInputManager = class
  private
    FShiftState: TShiftState;
    FUser: TCheckersVisualizer;
    procedure HookMessages(var Msg: TMsg; var Handled: Boolean);
    procedure SetVisualizer(const Value: TCheckersVisualizer);
    function GetX: Integer;
    function GetY: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    property ShiftState: TShiftState read FShiftState;
    property Visualizer: TCheckersVisualizer read FUser write SetVisualizer;
    property X: Integer read GetX;
    property Y: Integer read GetY;
  end;

function CheckersInput: TCheckersInputManager;

implementation

var
  vInput: TCheckersInputManager;

function CheckersInput: TCheckersInputManager;
begin
  if (vInput = nil) then
    vInput := TCheckersInputManager.Create();
  Result := vInput;
end;

constructor TCheckersInputManager.Create;
begin
  Application.OnMessage := HookMessages;
  FShiftState := [];
end;

procedure TCheckersInputManager.HookMessages(var Msg: TMsg; var Handled: Boolean);
begin
  Handled := False;
  if Assigned(Application.MainForm) then
  begin
    case Msg.message of
      WM_LBUTTONDOWN:
        FShiftState := FShiftState + [ssLeft];
      WM_RBUTTONDOWN:
        FShiftState := FShiftState + [ssRight];
      WM_MBUTTONDOWN:
        FShiftState := FShiftState + [ssMiddle];
      WM_LBUTTONUP:
        FShiftState := FShiftState - [ssLeft];
      WM_RBUTTONUP:
        FShiftState := FShiftState - [ssRight];
      WM_MBUTTONUP:
        FShiftState := FShiftState - [ssMiddle];
    end;
    case Msg.message of
      WM_MOUSELEAVE:
      begin
        FShiftState := [];
        FUser.Camera.IsMouseOnForm := False;
      end;
      WM_LBUTTONDOWN:
      begin
        FUser.Camera.MouseDown(X, Y, FShiftState);
      end;
      WM_RBUTTONDOWN:
      begin
        FUser.Camera.MouseDown(X, Y, FShiftState);
      end;
      WM_MBUTTONDOWN:
      begin
        FUser.Camera.MouseDown(X, Y, FShiftState);
      end;
      WM_RBUTTONUP:
      begin
        FUser.Camera.MouseUp(X, Y, FShiftState);
      end;
      WM_MOUSEMOVE:
      begin
        FUser.Camera.IsMouseOnForm := True;
        FUser.Camera.MouseMove(X, Y, FShiftState);
      end;
    end;
  end;
end;

function TCheckersInputManager.GetX: Integer;
begin
  if Assigned(Application.MainForm) then
    Result := Application.MainForm.ScreenToClient(Mouse.CursorPos).X
  else
    Result := 0;
end;

function TCheckersInputManager.GetY: Integer;
begin
  if Assigned(Application.MainForm) then
    Result := Application.MainForm.ScreenToClient(Mouse.CursorPos).Y
  else
    Result := 0;
end;

procedure TCheckersInputManager.SetVisualizer(const Value: TCheckersVisualizer);
begin
  FUser := Value;
end;

destructor TCheckersInputManager.Destroy;
begin
  inherited;
end;

initialization
finalization
if Assigned(vInput) then
  FreeAndNil(vInput);

end.

